/**
 * CoffeeMilk (C) 2010 Amen Hamdan
 * 
 * See the NOTICE file distributed with this work for additional 
 * information regarding copyright ownership.  This file is licenses
 * to you under the Apache License, Version 2.0 (the "License"); you 
 * may not use this file except in compliance with the License.  You 
 * may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 * implied. See the License for the specific language governing 
 * permissions and limitations under the License.    
 * 
 */
package ameen.rtm.coffeemilk.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import ameen.rtm.lib.types.NotesVector;
import ameen.rtm.lib.types.RtmTask;
import ameen.rtm.lib.types.RtmTaskNote;

public class NotesEditFrame extends JFrame implements PropertyChangeListener {
	private static final long serialVersionUID 	= 1L;
	private JPanel jContentPane 				= null;
	private JTabbedPane jTabbedPane 			= null;
	private JPanel jAddItemPanel 				= null;
	private JLabel jAddNotesLabel 				= null;

	private List<RtmTaskNote> notesTabList		= new ArrayList<RtmTaskNote>();
	private RtmTask rtmTask						= null;

	private Dimension buttonSize 				= new Dimension(16, 16);
	private Font editorFont 					= new Font("Dialog", Font.PLAIN, 14);
	private ImageIcon closeIcon 				= new ImageIcon(getClass().getResource("/ameen/rtm/coffeemilk/ui/close_small.png"));  //  @jve:decl-index=0:
	private ImageIcon commitIcon 				= new ImageIcon(getClass().getResource("/ameen/rtm/coffeemilk/ui/check_small.png"));
	private ImageIcon addIcon 					= new ImageIcon(getClass().getResource("/ameen/rtm/coffeemilk/ui/plus_small.png"));
	
	private MouseListener addNoteMouseListener = new MouseAdapter() {
		public void mouseClicked(MouseEvent e) {
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					rtmTask.addNote("created by CoffeeMilk", "");
				}
			});
		};
	};
	
	/**
	 * This is the default constructor
	 */
	public NotesEditFrame(RtmTask task) {
		super();
		rtmTask = task;
		rtmTask.getNotes().addPropertyChangeListener(this);
		initialize();
		
		jTabbedPane.setSelectedIndex(0);
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(400, 400);
		this.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/ameen/rtm/coffeemilk/ui/notes.png")));
		this.setContentPane(getJContentPane());
		this.setTitle("Notes: " + rtmTask.getName());
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJTabbedPane(), BorderLayout.CENTER);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jTabbedPane	
	 * 	
	 * @return javax.swing.JTabbedPane	
	 */
	private JTabbedPane getJTabbedPane() {
		if (jTabbedPane == null) {
			jTabbedPane = new JTabbedPane();
			createAddButton();
			Vector<RtmTaskNote> taskNotes = rtmTask.getNotes();
			if(taskNotes != null) {
				for(RtmTaskNote currentNote : taskNotes) {
					addNoteTab(currentNote);
				}
			}
		}
		return jTabbedPane;
	}

	
	/**
	 * This method initializes jAddItemPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJAddItemPanel() {
		if (jAddItemPanel == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.gridy = 0;
			jAddNotesLabel = new JLabel();
			jAddNotesLabel.setText("click here to add a note");
			jAddNotesLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
			jAddNotesLabel.addMouseListener(getAddNoteMouseListener());
			jAddItemPanel = new JPanel();
			jAddItemPanel.setLayout(new GridBagLayout());
			jAddItemPanel.add(jAddNotesLabel, gridBagConstraints);
		}
		return jAddItemPanel;
	}

	private void addNoteTab(final RtmTaskNote taskNote) {
		JScrollPane jScrollPane = new JScrollPane();
		final JEditorPane jEditorPane = new JEditorPane();
		jEditorPane.setFont(editorFont);
		jEditorPane.setText(taskNote.getText());
		jScrollPane.setViewportView(jEditorPane);
		
		JPanel panel = new JPanel();
		panel.setLayout(new FlowLayout());
		panel.setOpaque(false);
		final JLabel taskTitle = new JLabel(taskNote.getTitle());
		panel.add(taskTitle);
		panel.add(new JLabel("  "));
		panel.add(new JSeparator(SwingConstants.VERTICAL));
		panel.add(new JLabel("  "));
		JButton commitButton = createTabButton(commitIcon);
		commitButton.setToolTipText("sync the changes with RTM");
		JButton closeButton = createTabButton(closeIcon);
		closeButton.setToolTipText("delete this note");
		closeButton.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				int index = notesTabList.indexOf(taskNote);
				jTabbedPane.setSelectedIndex(index);
				
				int retVal = JOptionPane.showConfirmDialog(NotesEditFrame.this, 
														   "This will delete the currently selected note. Are you sure?", 
											               "Delete Note", JOptionPane.OK_CANCEL_OPTION);
				if(retVal == JOptionPane.OK_OPTION) {
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							rtmTask.deleteNote(taskNote);
							int index = notesTabList.indexOf(taskNote);
							notesTabList.remove(index);
							jTabbedPane.remove(index);
						}
					});
				}
			}
		});
				
		panel.add(commitButton);
		panel.add(closeButton);
	
		notesTabList.add(taskNote);
		int index = notesTabList.indexOf(taskNote);
		jTabbedPane.insertTab("X", null, jScrollPane, null, index);
		jTabbedPane.setTabComponentAt(index, panel);
		panel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				int index = notesTabList.indexOf(taskNote);
				jTabbedPane.setSelectedIndex(index);
			}
		});
		
		jEditorPane.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				taskTitle.setText(taskNote.getTitle() + " *");
			}
		});
		
		commitButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						rtmTask.updateNote(taskNote, jEditorPane.getText());
						taskTitle.setText(taskNote.getTitle());
					}
				});
			}
		});
	}

	private void createAddButton() {
		jTabbedPane.addTab("add item", getJAddItemPanel());	
		
		JPanel panel = new JPanel();
		panel.setOpaque(false);
		panel.add(new JLabel("add note"));
		panel.add(new JLabel("  "));
		panel.add(new JSeparator(SwingConstants.VERTICAL));
		panel.add(new JLabel("  "));
		JButton addButton = createTabButton(addIcon);
		addButton.addMouseListener(getAddNoteMouseListener());
		panel.add(addButton);
		
		jTabbedPane.setTabComponentAt(jTabbedPane.getTabCount()-1, panel);
		panel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				int activeIndex = jTabbedPane.getTabCount();
				jTabbedPane.setSelectedIndex(activeIndex-1);
			}
		});	}

	private JButton createTabButton(ImageIcon icon) {
		JButton retButton = new JButton("", icon);
		retButton.setPreferredSize(buttonSize);
		retButton.setContentAreaFilled(false);
		retButton.setBorder(BorderFactory.createEtchedBorder());
		return retButton;
	}

	public MouseListener getAddNoteMouseListener() {
		return addNoteMouseListener;
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if(evt.getPropertyName().equals(NotesVector.ELEMENT_ADDED)) {
			RtmTaskNote newNote = (RtmTaskNote) evt.getNewValue();
			addNoteTab(newNote);
			int index = notesTabList.indexOf(newNote);
			jTabbedPane.setSelectedIndex(index);
		}
	}
}
